
from latex_parser import ExpressionLanguage



class ExpressionSemantics(object):
    
    def evaluate(self, expr_tree):
        r = expr_tree.root
        subs = lambda: self.evaluate_subexpressions(expr_tree)

        E = ExpressionLanguage
        
        if r.kind is E.NUMBER:
            return int(r.text)
        elif r.kind is E.POW:
            l, r = subs()
            return l ** r
        elif r.kind is E.PLUS:
            l, r = ([0] + subs())[-2:]
            return l + r
        elif r.kind is E.MINUS:
            l, r = ([0] + subs())[-2:]
            return l - r
        elif r.kind is E.MUL:
            l, r = subs()
            return l * r
        elif r.kind is E.COMPOUND:
            if r.text == 'frac':
                l, r = subs()
                return float(l) / r
            else:
                return 0
        elif r.kind is ExpressionLanguage.ENCLOSED:
            return self.evaluate(expr_tree.subtrees[0])
        
    def evaluate_subexpressions(self, expr_tree):
        return [self.evaluate(s) for s in expr_tree.subtrees]
        

if __name__ == '__main__':
    from latex_parser import LaTeXFormulaParser
    
    inputs = [r"3^5",
              r"3^\textrm{5}",
              r"3^\frac{1}{2}",
              r"9^2+3*4",
              r"-5*8^\frac{1}{3}"]
   
    fparser = LaTeXFormulaParser()
    semantics = ExpressionSemantics()
   
    for input in inputs:
        expr = fparser(input)
        print expr
        print semantics.evaluate(expr)